home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / vballs11.zip / BALLS1.C < prev    next >
C/C++ Source or Header  |  1991-03-06  |  4KB  |  235 lines

  1. /*
  2.  * balls1.c  - Draw 3-D balls in 320x200x256 (VGA) mode
  3.  *
  4.  *             Uses BGI interface
  5.  *
  6.  * Adapted by: Scott J. Walter (GEnie:  S.Walter4)
  7.  *            
  8.  */
  9.  
  10. /* INCLUDES */
  11.  
  12. #include <stdio.h>
  13. #include <math.h>
  14. #include <stdlib.h>
  15. #include <conio.h>
  16. #include <dos.h>
  17. #include <time.h>
  18.  
  19. #include <graphics.h>
  20.  
  21.  
  22.  
  23. /* DEFINES */
  24.  
  25. #define TRUE  1
  26. #define FALSE 0
  27.  
  28.  
  29.  
  30.  
  31. /* TYPEDEFS */
  32.  
  33. typedef unsigned char UBYTE;
  34.  
  35. typedef struct {
  36.            UBYTE Rvalue;
  37.            UBYTE Gvalue;
  38.            UBYTE Bvalue;
  39.            } ColorValue;
  40.  
  41.  
  42.  
  43.  
  44. /* GLOBALS */
  45.  
  46. double     light[3] = { -2.0, -2.0, 3.0 };    /* light source upr lft */
  47. int        radius  = 40;
  48. ColorValue P[256];
  49.  
  50.  
  51.  
  52.  
  53. /* FUNCTIONS */
  54.  
  55. /*
  56.  * Normalize a vector to unit magnitude.  Calculate the magnitude as:
  57.  *
  58.  *     magnitude = sqrt ( x^2 + y^2 + z^2 )
  59.  *
  60.  * Normalize the vector by dividing each coordinate by the magnitude.
  61.  */
  62. void normalize(double this_vec[])
  63. {
  64.  double mag;
  65.  int count;
  66.  
  67.  
  68.  mag = 0.0;
  69.  
  70.  for(count = 0; count < 3; count++)
  71.   mag = mag + (this_vec[count] * this_vec[count]);
  72.  
  73.  mag = sqrt(mag);
  74.  
  75.  for(count = 0; count < 3; count++)
  76.   this_vec [count] = this_vec [count]/mag;
  77. }
  78.  
  79.  
  80.  
  81. /* Calculate the cosine of the angle between two vectors.
  82.  *
  83.  *     dot product = (x1 * x2) + (y1 * y2) + (z1 * z2)
  84.  */
  85. double dot_prod(double vec1[], double vec2[])
  86. {
  87.  double COSINE;
  88.  int count;
  89.  
  90.  
  91.  COSINE = 0.0;
  92.  
  93.  for (count = 0; count < 3; count++)
  94.   COSINE += vec1 [count] * vec2 [count];
  95.  
  96.  return (COSINE);
  97. }
  98.  
  99.  
  100.  
  101. void put_atom(int R, int index, int xc, int yc, double l_source[])
  102. {
  103.  double s_point[3];
  104.  int    R2 = R*R, color = 0;
  105.  double x, y, z, r, intensity;
  106.  
  107.  
  108.  normalize(l_source);               /* normalize the light source    */
  109.  
  110.  for(x=-R;x<=+R;x++)                 /* scan an area 2R x 2R     */
  111.   {
  112.   for(y=-R;y<=+R;y++)
  113.    {
  114.    r = (x*x) + (y*y);             /* check that the pixel is within a     */
  115.  
  116.    if(r <= R2)               /* circle of radius R               */
  117.     {
  118.     z = sqrt((R2)-r);          /* calculate the altitude of the point     */
  119.  
  120.     s_point[0] = x;            /* set the normal surface vector to the */
  121.     s_point[1] = y;            /* coordinates of the point         */
  122.     s_point[2] = z;
  123.  
  124.     intensity  = random(100);
  125.     intensity /= 100;
  126.  
  127.     intensity += 64 * dot_prod(s_point,l_source)/R;
  128.  
  129.     color = (int)intensity;
  130.  
  131.     color = color<0 ? 0 : (color> 63 ? 63 : color);
  132.  
  133.     putpixel(x+xc,y+yc,index*64 + color);
  134.     }
  135.    }
  136.   }
  137. }
  138.  
  139.  
  140.  
  141. void VGASetAllPalette(void)
  142. {
  143.  struct REGPACK r;
  144.  
  145.  
  146.  r.r_ax = 0x1012;
  147.  r.r_bx = 0x0000;
  148.  r.r_cx = 0x0100;
  149.  r.r_es = FP_SEG(&P[0]);
  150.  r.r_dx = FP_OFF(&P[0]);
  151.  
  152.  intr(0x10, &r);
  153. }
  154.  
  155.  
  156.  
  157. void Hsi2Rgb(float H, float S, float I, int palpos)
  158. {
  159.  float T, Rv, Gv, Bv;
  160.  float Pi = 3.14159265358979;
  161.  
  162.  
  163.  H = H < 0.0 ? 1.0 + H : (H > 1.0 ? H - 1.0 : H);
  164.  S = S < 0.0 ? 1.0 + S : (S > 1.0 ? S - 1.0 : S);
  165.  I = I < 0.0 ? 1.0 + I : (I > 1.0 ? I - 1.0 : I);
  166.  
  167.  T  = 2.0 * Pi * H;
  168.  
  169.  Rv = 1 + S * sin(T - 2 * Pi / 3);
  170.  Gv = 1 + S * sin(T);
  171.  Bv = 1 + S * sin(T + 2 * Pi / 3);
  172.  
  173.  T = 63.999 * I / 2;
  174.  
  175.  P[palpos].Rvalue = (UBYTE)(Rv * T);
  176.  P[palpos].Gvalue = (UBYTE)(Gv * T);
  177.  P[palpos].Bvalue = (UBYTE)(Bv * T);
  178. }
  179.  
  180.  
  181.  
  182. int huge DetectVGA256(void)
  183. {
  184.  int gdriver, gmode;
  185.  
  186.  
  187.  detectgraph(&gdriver, &gmode);
  188.  
  189.  if((gdriver==VGA)||(gdriver==MCGA))
  190.    return 0;                    /* Default video mode = 0 */
  191.  else
  192.    return grError;             /* Couldn't detect hardware */
  193. }
  194.  
  195.  
  196.  
  197.  
  198. /* MAIN */
  199.  
  200. void main(void)
  201. {
  202.  int Y, Z, ErrorCode, Driver = DETECT, Mode;
  203.  
  204.  
  205.  installuserdriver("VGA256", DetectVGA256);
  206.  
  207.  initgraph(&Driver, &Mode, "");
  208.  
  209.  ErrorCode = graphresult();
  210.  
  211.  if(ErrorCode!=grOk)
  212.   {
  213.   printf("Error: %s\n", grapherrormsg(ErrorCode));
  214.   exit(1);
  215.   }
  216.  
  217.  randomize();
  218.  
  219.  for(Y=0;Y<4;Y++)
  220.   for(Z=0;Z<64;Z++)
  221.    Hsi2Rgb(0.25+(float)Y/5.0, 1.0, (float)Z/64.0, Y*64+Z);
  222.  
  223.  VGASetAllPalette();
  224.  
  225.  for(Y=0;Y<2;Y++)
  226.   for(Z=0;Z<2;Z++)
  227.    put_atom(radius, Y*2+Z, 80+160*Z, 50+100*Y, light);
  228.  
  229.  putch(7);
  230.  
  231.  getch();
  232.  
  233.  closegraph();
  234. }
  235.